package org.atlantis.ymer.command;

import java.util.Collection;

import org.atlantis.ymer.YmerException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;

public abstract class JsonCommand implements Command {

	protected static final ObjectMapper mapper = new ObjectMapper();
	protected ObjectNode node;

	public static String parseCommands(Collection<JsonCommand> commands) {
		ArrayNode nodes = mapper.createArrayNode();
		for (JsonCommand command : commands) {
			nodes.add(command.toJson());
		}
		try {
			return mapper.writeValueAsString(nodes);
		} catch (Exception e) {
			throw new YmerException("Parse commands to json error.", e);
		}
	}

	protected abstract JsonNode toJson();

	@Override
	public String getContent() {
		try {
			return mapper.writeValueAsString(toJson());
		} catch (Throwable e) {
			throw new YmerException("parse " + this.getClass() + " to json error.", e);
		}
	}

	public static Command parseJson(String json) {
		try {
			JsonNode rootNode = mapper.readTree(json);
			CommandType type = CommandType.of(rootNode.get("type").asInt());
			JsonNode dataNode = rootNode.get("data");
			switch (type) {
			case DISCONNECT:
				return DisconnectCommand.instance;
			case PONG:
				return PongCommand.instance;
			case PUB:
				return new PubCommand(dataNode.get("topic").asText(), dataNode.get("message"));
			default:
				return null;
			}
		} catch (Exception e) {
			throw new YmerException("Json(" + json + ") convert to DataFrame error.", e);
		}
	}
}
